#include "protreewidget.h"
#include <QDebug>
#include <QDir>
#include "protreewidgetitem.h"
#include "const.h"
#include <QGuiApplication>
#include <QMenu>
#include <QCursor>
#include <QFileDialog>


// 调用父类的构造函数
ProTreeWidget::ProTreeWidget(QWidget *parent)
    :QTreeWidget(parent)
{
    // 暂且不知道何用                            TODO
    // qRegisterMetaType<QVector<int> >("QVector<int>");
    // 把QTreeWidget 中的 1 隐藏
    this->header()->hide();

    // 关联信号槽：当鼠标点击根目录弹出菜单：导入文件、轮询播放
    connect(this,&ProTreeWidget::itemPressed,this,&ProTreeWidget::SlotHanderItemPressed);
    // 初始化 导入文件的动作
    _act_imoprt_file = new QAction(QIcon(":/QIcon/import.png"),"导入文件",this);
    // 关联信号槽：点击导入文件动作时，完成导入文件的操作
    connect(_act_imoprt_file,&QAction::triggered,this,&ProTreeWidget::SlotHanderActImportDir);
}

void ProTreeWidget::SlotHanderItemPressed(QTreeWidgetItem *item, int column)
{
    (void)column;
    qDebug() << "SlotHanderItemPressed" << endl;
    // 判断是否是鼠标右键点击
    if(QGuiApplication::mouseButtons() == Qt::RightButton)
    {
        // 创建菜单栏
        // 不要在堆上申请，会造成类似内存泄漏
        // 每次点击ProTree是全局的生命周期
        QMenu menu(this);
        // 获取类型
        int type = (int)item->type();
        // 如果是根目录
        if(type == TreeItemPro)
        {
            // 先保存下来这个节点
            _right_btn_item = item;
            menu.addAction(_act_imoprt_file);
            // 菜单淡出位置为鼠标的位置
            menu.exec(QCursor::pos());
        }
    }
}

// 获取要导入图片的文件夹
void ProTreeWidget::SlotHanderActImportDir()
{
    QFileDialog file_dialog;
    // 将文件对话框设置成导入目录模式
    file_dialog.setFileMode(QFileDialog::Directory);
    file_dialog.setWindowTitle("导入对应的文件夹");
    // 弹出的文件对话框设置一个当前的所在位置
    QString path = "";
    // 做一个判断，执行到这_right_btn_item为空的几率很小，
    // 前面弹出菜单时已经设置了,以防万一做一次判断
    if(!_right_btn_item)
    {
        qDebug() << "_right_btn_item is empty";
        return;
    }
    // 获取路径
    path = dynamic_cast<ProTreeWidgetItem*>(_right_btn_item)->GetPath();
    // 设置弹出的文件对话框所在路径
    file_dialog.setDirectory(path);
    // 设置文件对话框的模式
    file_dialog.setViewMode(QFileDialog::Detail);

    QStringList filenames;
    // 文件对话框执行成功时，获取路径
    if(file_dialog.exec())
    {
        filenames = file_dialog.selectedFiles();
    }
    if(filenames.length() <= 0)
    {
        qDebug() << "filenames.length() <= 0";
        return;
    }
    QString import_path = filenames.at(0);
    qDebug() << "import_path: " << import_path;
    // 文件个数
    int file_count = 0;
    // 创建模态对话框-进度条
    _dialog_progress = new QProgressDialog(this);


    // 创建线程 完成导入文件工作
    // 线程的参数是const & ,我引用传递
    _thread_importDir = std::make_shared<ProTreeThread>(std::ref(import_path),
                                                        std::ref(path),std::ref(file_count),
                                                        _right_btn_item,_right_btn_item,this,nullptr);


    // 关联信号槽 处理导入线程中发出的SigUpdateProgress信号
    connect(_thread_importDir.get(),&ProTreeThread::SigUpdateProgress,this,&ProTreeWidget::SlotHandlerUpdatePro);
    connect(_thread_importDir.get(),&ProTreeThread::SigFinishProgress,this,&ProTreeWidget::SlotHandlerFinishPro);

    // 弹出的进度对话框取消后，会发送canceld信号
    connect(_dialog_progress,&QProgressDialog::canceled,this,&ProTreeWidget::SlotHanlderCancel);
    // 取消对话框即要终止导入文件夹的线程，通过发送信号给 thread_importDir
    connect(this,&ProTreeWidget::SigCancelImport,_thread_importDir.get(),&ProTreeThread::SlotCancelImport);

    // 启动导入文件夹线程
    // Qt中启动线程是start 而不是run
    // run是线程的入口函数
    _thread_importDir->start();

    // 设置dialog_progress的界面,并执行。
    // 在执行之前必须完成信号槽的连接
    _dialog_progress->setWindowTitle("Please wait...");

    _dialog_progress->setFixedWidth(PROGRESS_WIDTH);
    _dialog_progress->setRange(0,PROGRESS_WIDTH);
    // 执行进度条对话框
    _dialog_progress->exec();

}
// 更新进度条
void ProTreeWidget::SlotHandlerUpdatePro(int file_count)
{
    qDebug() << "count is " << file_count;
    if(!_dialog_progress)
    {
        qDebug() << "_dialog_progress is empty" << endl;
        return;
    }

    _dialog_progress->setValue(file_count % PROGRESS_WIDTH);
}
// 进度条完成
void ProTreeWidget::SlotHandlerFinishPro()
{

    _dialog_progress->setValue(PROGRESS_WIDTH);
    // 在下一个事件周期释放 进度条对话框
    _dialog_progress->deleteLater();
}
// 取消导入文件操作
void ProTreeWidget::SlotHanlderCancel()
{
    emit SigCancelImport();
    delete _dialog_progress;
    _dialog_progress = nullptr;
}

void ProTreeWidget::AddItemToProTree(const QString &name, const QString &path)
{
    // 构建对应的文件路径名
    QDir dir(path);
    // 拼接name
    QString file_path = dir.absoluteFilePath(name);
    // 使用集合判断该节点曾经是否加入过
    // 我们需要使用QSet来判断
    if(_set_path.find(file_path) != _set_path.end())
    {
        //已经存在
        qDebug() << file_path << " has loaded";
        return;
    }
    // 构建项目用的文件夹
    QDir pro_dir(file_path);
    // 如果文件夹不存在则创建它
    if(!pro_dir.exists())
    {
        // 创建路径
        bool enable = pro_dir.mkpath(file_path);
        // mkdir 创建子目录
        // pro_dir.mkdir(file_path);
        if(!enable)
        {
            qDebug() << "pro_dir make path failed";
            return;
        }
    }
    // 加入路径集合中
    _set_path.insert(file_path);
    // 在界面上创建一个节点
    ProTreeWidgetItem* item = new ProTreeWidgetItem(this,name,file_path,TreeItemPro);
    item->setData(0,Qt::DisplayRole,name);
    item->setData(0,Qt::DecorationRole,QIcon(":/QIcon/dir.png"));
    item->setData(0,Qt::ToolTipRole,file_path);

}


